//
//  CustomConvertible.swift
//  TTProduct
//
//  Created by Toj on 1/15/21.
//  基本类型强制类型转换
//

import CoreGraphics

// MARK: - extension ExtString
public extension ExtString where Self : StringProtocol {
    
    // 转Int
    var to_int: Int {
        var val = 0
        if let string = self as? String {
            val = Int(string) ?? 0
        }
        return val
    }
    
    var to_int8: Int8 {
        var val:Int8 = 0
        if let string = self as? String {
            val = Int8(string) ?? 0
        }
        return val
    }
    
    var to_int16: Int16 {
        var val:Int16 = 0
        if let string = self as? String {
            val = Int16(string) ?? 0
        }
        return val
    }
    
    var to_int32: Int32 {
        var val:Int32 = 0
        if let string = self as? String {
            val = Int32(string) ?? 0
        }
        return val
    }
    
    var to_int64: Int64 {
        var val:Int64 = 0
        if let string = self as? String {
            val = Int64(string) ?? 0
        }
        return val
    }
    
    var to_uint: UInt {
        var val:UInt = 0
        if let string = self as? String {
            val = UInt(string) ?? 0
        }
        return val
    }
    
    var to_uint8: UInt8 {
        var val:UInt8 = 0
        if let string = self as? String {
            val = UInt8(string) ?? 0
        }
        return val
    }
    
    var to_uint16: UInt16 {
        var val:UInt16 = 0
        if let string = self as? String {
            val = UInt16(string) ?? 0
        }
        return val
    }
    
    var to_uint32: UInt32 {
        var val:UInt32 = 0
        if let string = self as? String {
            val = UInt32(string) ?? 0
        }
        return val
    }
    
    var to_uint64: UInt64 {
        var val:UInt64 = 0
        if let string = self as? String {
            val = UInt64(string) ?? 0
        }
        return val
    }
    
    var to_double: Double {
        var val:Double = 0
        if let string = self as? String {
            val = Double(string) ?? 0
        }
        return val
    }
    
    var to_float: Float {
        var val:Float = 0
        if let string = self as? String {
            val = Float(string) ?? 0
        }
        return val
    }
    
    var to_float32: Float32 {
        var val:Float32 = 0
        if let string = self as? String {
            val = Float32(string) ?? 0
        }
        return val
    }
    
    var to_float64: Float64 {
        return to_double
    }
    
    var to_float80: Float32 {
        var val:Float32 = 0
        if let string = self as? String {
            val = Float32(string) ?? 0
        }
        return val
    }
    
    var to_cgfloat: CGFloat {
        let float = to_float64
        let val = CGFloat(float)
        return val
    }
}

// MARK: - extension ExtInt
public extension ExtInt where Self : BinaryInteger {
    
    var to_string: String {
        return String(self)
    }
    
    var to_int8: Int8 {
        return Int8(self)
    }
    
    var to_int16: Int16 {
        return Int16(self)
    }
    
    var to_int32: Int32 {
        return Int32(self)
    }
    
    var to_int64: Int64 {
        return Int64(self)
    }
    
    var to_uint: UInt {
        return UInt(self)
    }
    
    var to_uint8: UInt8 {
        return UInt8(self)
    }
    
    var to_uint16: UInt16 {
        return UInt16(self)
    }
    
    var to_uint32: UInt32 {
        return UInt32(self)
    }
    
    var to_uint64: UInt64 {
        return UInt64(self)
    }
    
    // == Float64
    var to_double: Double {
        return Double(self)
    }
    
    // == Float32
    var to_float: Float {
        return Float(self)
    }
    
    // == Float
    var to_float32: Float32 {
        return Float32(self)
    }
    
    // == Double
    var to_float64: Float64 {
        return Float64(self)
    }
    
    var to_cgfloat: CGFloat {
        return CGFloat(self)
    }
}

// MARK: - extension ExtFloat
public extension ExtFloat where Self : LosslessStringConvertible {
    
    var to_string: String {
        return String(self)
    }
}

public extension ExtFloat where Self : BinaryFloatingPoint {
    
    var to_int: Int {
        return Int(self)
    }
    
    var to_int8: Int8 {
        return Int8(self)
    }
    
    var to_int16: Int16 {
        return Int16(self)
    }
    
    var to_int32: Int32 {
        return Int32(self)
    }
    
    var to_int64: Int64 {
        return Int64(self)
    }
    
    var to_uint: UInt {
        return UInt(self)
    }
    
    var to_uint8: UInt8 {
        return UInt8(self)
    }
    
    var to_uint16: UInt16 {
        return UInt16(self)
    }
    
    var to_uint32: UInt32 {
        return UInt32(self)
    }
    
    var to_uint64: UInt64 {
        return UInt64(self)
    }
    
    // == Float32
    var to_float: Float {
        return Float(self)
    }
    
    // == toFloat
    var to_float32: Float32 {
        return Float32(self)
    }
    
    var to_float64: Float64 {
        return Float64(self)
    }
    
    var to_cgfloat: CGFloat {
        return CGFloat(self)
    }
}

// MARK: - extension String
extension String {
    
    var to_data: Data? {
        return data(using: .utf8)
    }
    
    var to_dictionary: [String: Any]? {
        return to_dictionary(t: Any.self)
    }
    
    func to_dictionary<Value>(t:Value) -> [String: Value]? {
        guard let data = to_data else { return nil }
        let json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments)
        
        return json as? Dictionary<String, Value>
    }
    
    var to_array: [Any]? {
        return to_array(t: Any.self)
    }
    
    func to_array<T>(t:T) -> [T]? {
        guard let data = to_data else { return nil }
        let object = try? JSONSerialization.jsonObject(with: data, options: .allowFragments)
        
        return object as? [T]
    }
}

public extension Dictionary {
    
    var to_json: String? {
        guard let data = to_data else { return nil }
        let json = String(data: data, encoding:.utf8)
        return json
    }
    
    var to_data: Data? {
        return try? JSONSerialization.data(withJSONObject: self, options: .fragmentsAllowed)
    }
}

public extension Array {

    var to_json: String? {
        guard let data = to_data else { return nil }
        let json = String(data: data, encoding:.utf8)
        return json
    }
    
    var to_data: Data? {
        return try? JSONSerialization.data(withJSONObject: self, options: .fragmentsAllowed)
    }
}

public extension Data {
    
    var to_json: String? {
        return String(data: self, encoding:.utf8)
    }
    
    var to_dictionary: [String: Any]? {
        return to_dictionary(t: Any.self)
    }
    
    func to_dictionary<Value>(t:Value) -> [String: Value]? {
        let json = try? JSONSerialization.jsonObject(with: self, options: .allowFragments)
        
        return json as? Dictionary<String, Value>
    }
    
    var to_array: [Any]? {
        return to_array(t: Any.self)
    }
    
    func to_array<T>(t:T) -> [T]? {
        let object = try? JSONSerialization.jsonObject(with: self, options: .allowFragments)
        
        return object as? [T]
    }
}
